package com.xcesys.extras.dataobject;

import java.beans.PropertyChangeListener;
import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;

/**
 * <p>
 * Abstract class that adds java bean PropertyChangeSupport to Pojo, subclass
 * can add and remove PropertyChangeListener to listen java bean properties
 * changed event, it is very useful to eclipse data binding and other purpose.
 * <p>
 * Subclass that extends this class can fire property change event in their
 * properties' setter method, any listeners will be notified while setter method
 * invoked.
 * </p>
 * Example:
 * 
 * <pre>
 * public void setName(String name) {
 * 	Object oldValue = this.name;
 * 	this.name = name;
 * 	firePropertyChange(&quot;resName&quot;, oldValue, name);
 * }
 * </pre>
 * 
 * @author Danne
 */
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "AbstractDataObject")
public abstract class AbstractDataObject implements IdentityObject,
		Serializable {

	// private PropertyChangeSupport propertyChangeSupport = new
	// PropertyChangeSupport(
	// this);

	private static final long serialVersionUID = -3005778726737560802L;
	/** dirty flag indicate object changed */
	@XmlAttribute(name = "Dirty")
	private boolean dirty;
	/** editing flag indicates whether this object is being editing. */
	@XmlAttribute(name = "Editing")
	private boolean editing;
	/** entity primary key id */
	@XmlAttribute(name = "Id")
	protected Long id;
	/** physical deleted flag for remove object operation */
	@XmlAttribute(name = "Removed")
	private boolean removed;
	@XmlAttribute(name = "New")
	private boolean nuw;

	public AbstractDataObject() {
	}

	public void addPropertyChangeListener(PropertyChangeListener listener) {
		// propertyChangeSupport.addPropertyChangeListener(listener);
	}

	public void addPropertyChangeListener(String propertyName,
			PropertyChangeListener listener) {
		// propertyChangeSupport.addPropertyChangeListener(propertyName,
		// listener);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		AbstractDataObject other = (AbstractDataObject) obj;
		if (id == null) {
			return false;
		} else if (!id.equals(other.id)) {
			return false;
		}
		return true;
	}

	protected void firePropertyChange(String propertyName, Object oldValue,
			Object newValue) {
		// propertyChangeSupport.firePropertyChange(propertyName, oldValue,
		// newValue);
	}

	@Override
	public Long getId() {
		return id;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	public boolean isDirty() {
		return dirty;
	}

	public boolean isEditing() {
		return editing;
	}

	public boolean isNuw() {
		return getId() == null || getId().longValue() == 0;
	}

	public boolean isRemoved() {
		return removed;
	}

	public void removePropertyChangeListener(PropertyChangeListener listener) {
		// propertyChangeSupport.removePropertyChangeListener(listener);
	}

	public void removePropertyChangeListener(String propertyName,
			PropertyChangeListener listener) {
		// propertyChangeSupport.removePropertyChangeListener(propertyName,
		// listener);
	}

	public void setDirty(boolean dirty) {
		Object oldValue = this.dirty;
		this.dirty = dirty;
		firePropertyChange("dirty", oldValue, dirty);
	}

	public void setEditing(boolean editing) {
		Object oldValue = this.editing;
		this.editing = editing;
		firePropertyChange("editing", oldValue, editing);
	}

	@Override
	public void setId(Long id) {
		Object oldValue = this.id;
		this.id = id;
		firePropertyChange("id", oldValue, id);
	}

	public void setNuw(boolean nuw) {
		Object oldValue = this.nuw;
		this.nuw = nuw;
		firePropertyChange("nuw", oldValue, nuw);
	}

	public void setRemoved(boolean removed) {
		Object oldValue = this.removed;
		this.removed = removed;
		firePropertyChange("removed", oldValue, removed);
	}

}
